package com.jiang.entity;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

/**
 * 对等网路，也是一个线程
 */
public class PeerNetwork extends Thread{
    private static final Logger LOGGER = LoggerFactory.getLogger(PeerNetwork.class);
    private int port;
    private boolean runFlag = true;

    public List<PeerThread> peerThreads;//对等线程集合
    public List<String> peers;//访问的客户端的套接字，ip+port

    /**
     * 默认构造
     */
    public PeerNetwork() {
        port = 8015;
        this.peers = new ArrayList<String>();
        this.peerThreads = new ArrayList<PeerThread>();
    }

    public PeerNetwork(int port) {
        this.port = port;
        this.peers = new ArrayList<String>();
        this.peerThreads = new ArrayList<PeerThread>();
    }

    @Override
    public void run() {
        try {
            ServerSocket serverSocket = new ServerSocket(port);//新建服务器监听端口
            while (runFlag){//当这个运行标志一直是真时，则一直建立线程
                PeerThread peerThread = new PeerThread(serverSocket.accept());//由客户端的套接字建立对等线程
                peerThreads.add(peerThread);
                //启动该对等线程
                peerThread.start();
            }
            serverSocket.close();//不需要运行，则没有必要监听了。
        } catch (IOException e) {
            LOGGER.error("TCP 端口监听出现问题",e);
        }
    }


    /**
     * 建立连接
     * @param host
     * @param port
     */
    public void connect(String host, int port){
        Socket socket = null;
        try {
            socket = new Socket();//新建套接字，客户端套接字
            /**
             * 使用指定的超时值将此套接字连接到服务器。
             * 零超时被解释为无限超时。 然后，连接将被阻塞，直到建立或发生错误。
             */
            socket.connect(new InetSocketAddress(host, port), 10000);//连接该ip的端口，最多时间为10s
            String remoteHost = socket.getInetAddress().getHostAddress();//获得服务器ip地址
            int remotePort = socket.getPort();
            LOGGER.info("socket "+ remoteHost+":"+remotePort+" connected.");
            peers.add(remoteHost+":"+remotePort);//将这个服务器套接字放在peers中，对等网络中
            PeerThread pt = new PeerThread(socket);
            peerThreads.add(pt);
            pt.start();
        } catch (IOException e) {
            LOGGER.warn("socket "+host+":"+port+" can't connect.", e);
        }
    }


    public void broadcast(String data) {
        for(PeerThread pt:peerThreads){
            //对每个客户端
            LOGGER.info("Sent:: "+data);
            if(pt != null){
                pt.send(data);

            }
        }
    }
}
